package cn.ljy.mes.service.impl;

import cn.ljy.authority.service.impl.IBaseService;
import cn.ljy.common.exception.model.MyConfirmException;
import cn.ljy.common.exception.model.MyServiceException;
import cn.ljy.mes.dao.mapper.WmsMaterialInventoryDetailMapper;
import cn.ljy.mes.dao.mapper.WmsMaterialInventoryDetailRelocationLogMapper;
import cn.ljy.mes.dao.mapper.WmsWarehouseAreaMapper;
import cn.ljy.mes.dao.mapper.WmsWarehouseSeatMapper;
import cn.ljy.mes.model.WmsWarehouse;
import cn.ljy.mes.model.WmsWarehouseArea;
import cn.ljy.mes.model.WmsWarehouseSeat;
import cn.ljy.mes.model.query.*;
import cn.ljy.mes.service.WmsWarehouseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
//@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor= MyRollBackException.class)
@Validated//表示开启sprint的校检框架，会自动扫描方法里的@Valid（@Valid注解一般写在接口即可）
@Slf4j
public class IWmsWarehouseService extends IBaseService<WmsWarehouse, WmsWarehouseQuery> implements WmsWarehouseService {
    @Autowired
    private WmsWarehouseAreaMapper wmsWarehouseAreaMapper;
    @Autowired
    private WmsWarehouseSeatMapper wmsWarehouseSeatMapper;
    @Autowired
    private WmsMaterialInventoryDetailMapper materialInventoryDetailMapper;
    @Autowired
    private WmsMaterialInventoryDetailRelocationLogMapper materialInventoryDetailRelocationLogMapper;

    //设置关联属性
    @Override
    protected void enrichEntityFields(WmsWarehouse wmsWarehouse){
        if(wmsWarehouse!=null){
            //获取仓库下的库区数量
            WmsWarehouseAreaQuery wmsWarehouseAreaQuery=new WmsWarehouseAreaQuery();
            wmsWarehouseAreaQuery.setWarehouse(wmsWarehouse);
            wmsWarehouse.setAreaNumber(wmsWarehouseAreaMapper.count(wmsWarehouseAreaQuery));
            //获取仓库下的库位数量
            WmsWarehouseSeatQuery wmsWarehouseSeatQuery=new WmsWarehouseSeatQuery();
            wmsWarehouseSeatQuery.setWarehouse(wmsWarehouse);
            wmsWarehouse.setSeatNumber(wmsWarehouseSeatMapper.count(wmsWarehouseSeatQuery));
            //获取仓库下的物料存储位
            WmsMaterialInventoryDetailQuery materialInventoryDetailQuery=new WmsMaterialInventoryDetailQuery();
            WmsWarehouseArea warehouseArea=new WmsWarehouseArea();
            warehouseArea.setWarehouse(wmsWarehouse);
            WmsWarehouseSeat warehouseSeat=new WmsWarehouseSeat();
            warehouseSeat.setWarehouseArea(warehouseArea);
            materialInventoryDetailQuery.setWarehouseSeat(warehouseSeat);
            wmsWarehouse.setMaterialInventoryDetailNumber(materialInventoryDetailMapper.count(materialInventoryDetailQuery));
        }
    }

    @Override
    protected void beforeDelete(Serializable[] ids) {
        Map<String,String> errorMessageMap=new HashMap();
        for(Serializable id:ids){
            //获取仓库详情
            WmsWarehouse wmsWarehouse=mapper.findById(id);
            if(wmsWarehouse!=null){
                //获取仓库下的库区数量
                WmsWarehouseAreaQuery wmsWarehouseAreaQuery=new WmsWarehouseAreaQuery();
                wmsWarehouseAreaQuery.setWarehouse(new WmsWarehouse(id.toString()));
                int wmsWarehouseAreaNumber=wmsWarehouseAreaMapper.count(wmsWarehouseAreaQuery);
                if(wmsWarehouseAreaNumber>0){
                    errorMessageMap.put(wmsWarehouse.getName(),String.valueOf(wmsWarehouseAreaNumber));
                }
            }
        }
        //确定是否抛出错误信息
        if(errorMessageMap.size()>0){
            throw new MyConfirmException("%s已存在%s个库区",errorMessageMap);
        }
    }

    @Override
    protected void beforeForceDelete(Serializable[] ids) {
        List<WmsWarehouseArea> allAreas=new ArrayList<>();//定义和获取所有仓库下的库区信息
        List<WmsWarehouseSeat> allSeats=new ArrayList<>();//定义和获取所有仓库下的库位信息
        for(Serializable id:ids){
            if(id!=null){
                WmsWarehouse wmsWarehouse=mapper.findById(id);
                if(wmsWarehouse!=null){
                    //1.先判断仓库下是否有物料存储位，如果有就不允许删除
                    WmsMaterialInventoryDetailQuery materialInventoryDetailQuery=new WmsMaterialInventoryDetailQuery();
                    WmsWarehouseArea warehouseArea=new WmsWarehouseArea();
                    warehouseArea.setWarehouse(wmsWarehouse);
                    WmsWarehouseSeat warehouseSeat=new WmsWarehouseSeat();
                    warehouseSeat.setWarehouseArea(warehouseArea);
                    materialInventoryDetailQuery.setWarehouseSeat(warehouseSeat);
                    int materialInventoryDetailNumber=materialInventoryDetailMapper.count(materialInventoryDetailQuery);
                    if(materialInventoryDetailNumber>0){
                        throw new MyServiceException(String.format("强制删除失败：%s内有%d个物料存储位在使用中。",wmsWarehouse.getName(),materialInventoryDetailNumber));
                    }
                    //2.先判断库位是否已经有使用的日志，即使当前已经没有物料在库位中，也不允许删除库位信息
                    //3.1 判断源库位
                    WmsMaterialInventoryDetailRelocationLogQuery materialInventoryDetailRelocationLogQuery=new WmsMaterialInventoryDetailRelocationLogQuery();
                    materialInventoryDetailRelocationLogQuery.setWarehouseSeatOfSource(warehouseSeat);
                    int materialInventoryDetailRelocationLogNumber=materialInventoryDetailRelocationLogMapper.count(materialInventoryDetailRelocationLogQuery);
                    if(materialInventoryDetailRelocationLogNumber>0){
                        throw new MyServiceException(String.format("强制删除失败：仓库%s虽然已经没有物料在使用，但是已经有出库的使用记录，无法删除！",wmsWarehouse.getName()));
                    }
                    //3.2 判断目标库位
                    materialInventoryDetailRelocationLogQuery=new WmsMaterialInventoryDetailRelocationLogQuery();
                    materialInventoryDetailRelocationLogQuery.setWarehouseSeatOfTarget(warehouseSeat);
                    materialInventoryDetailRelocationLogNumber=materialInventoryDetailRelocationLogMapper.count(materialInventoryDetailRelocationLogQuery);
                    if(materialInventoryDetailRelocationLogNumber>0){
                        throw new MyServiceException(String.format("删除失败：仓库%s虽然已经没有物料在使用，但是已经有入库的使用记录，无法删除！",wmsWarehouse.getName()));
                    }
                    //3.获取库区集合
                    WmsWarehouseAreaQuery wmsWarehouseAreaQuery=new WmsWarehouseAreaQuery();
                    wmsWarehouseAreaQuery.setWarehouse(wmsWarehouse);
                    allAreas.addAll(wmsWarehouseAreaMapper.findAll(wmsWarehouseAreaQuery));
                    //3.获取库位集合
                    WmsWarehouseSeatQuery wmsWarehouseSeatQuery=new WmsWarehouseSeatQuery();
                    wmsWarehouseSeatQuery.setWarehouse(wmsWarehouse);
                    allSeats.addAll(wmsWarehouseSeatMapper.findAll(wmsWarehouseSeatQuery));
                }
            }
        }
        //4.先删除所有库位，再删除库区
        wmsWarehouseSeatMapper.deleteAllIn(allSeats);
        wmsWarehouseAreaMapper.deleteAllIn(allAreas);
    }
}
